const express = require("express");
const mongoose = require('mongoose');
const cors = require('cors');
const {saveLog, checkLogCollectionExists, isValidDateTimeFormat} = require("./tools/toolForLogs");
const useragent = require("ua-parser-js");


// ========== 配置区域 ==========
const {MONGO_URI, PORT, LOG_COLLECTION, PREFIX} = require("./config/config");
const {setDataAgain} = require("./tools/func");
// ==============================


const app = express();


/**
 * 功能说明：
 * 1. 查询集合数据
 *  GET http://localhost:${PORT}${PREFIX}/{collection}
 * 支持的查询参数：
 *  - filter: JSON 格式的过滤条件（需要进行 encodeURIComponent 编码）
 *  - sort: JSON 格式的排序规则（需要进行 encodeURIComponent 编码）
 *  - page: 页码（默认为 1）
 *  - size: 每页数据条数（默认为 10）
 *
 * # 不进行编码的示例（仅作参考，实际使用需编码）
 * GET http://localhost:${PORT}${PREFIX}/user?filter={"username":"111111"}&sort={"createTime":-1}&page=1&size=10
 *
 *
 * 2. 日志查询接口
 * GET http://localhost:${PORT}${PREFIX}/logs
 * 支持的查询参数：
 *  - user: 查询指定用户的日志
 *  - collection: 查询指定集合的访问日志
 *  - status: 查询指定状态的日志（success||error）
 *  - startTime: 查询起始时间（格式：YYYY-MM-DD HH:mm:ss）
 *  - endTime: 查询结束时间（格式：YYYY-MM-DD HH:mm:ss）
 *  - sort: 排序规则（默认按时间倒序）
 *  - page: 页码（默认为 1）
 *  - size: 每页数据条数（默认为 10）
 * 使用事例:
 *  # 分页查询日志
 *  - GET http://localhost:${PORT}${PREFIX}/logs?page=1&size=10
 *
 *  # 查询某个用户的日志
 *  - GET http://localhost:${PORT}${PREFIX}/logs?user=kevin
 *
 *  # 查询某个集合的访问日志
 *  - GET http://localhost:${PORT}${PREFIX}/logs?collection=orders
 *
 *  # 查询某个时间范围的日志
 *  - GET http://localhost:${PORT}${PREFIX}/logs?startTime=2025-09-01&endTime=2025-09-02
 *
 *  # 查询失败的调用
 *  - GET http://localhost:${PORT}${PREFIX}/logs?status=success
 *
 *  # 查询失败的调用
 *  - GET http://localhost:${PORT}${PREFIX}/logs?status=error
 */
async function startServer() {
    // 连接 MongoDB
    await mongoose.connect(MONGO_URI, {});
    console.log("✅ MongoDB connected:", MONGO_URI);

    // 获取所有集合
    const collections = await mongoose.connection.db.listCollections().toArray();
    console.log("📦 Found collections:", collections.map(c => c.name));


    // 确保日志集合存在
    await checkLogCollectionExists(mongoose, collections, LOG_COLLECTION)


    app.use(cors());


    // 动态注册所有集合的查询路由
    for (let item of collections) {
        const {name} = item;

        if (name === 'logs') continue;

        app.get(`${PREFIX}/${name}`, async (req, res) => {

            const user = req.headers["x-user"] || "anonymous";
            const IP = req.headers["x-forwarded-for"] || req.socket.remoteAddress;
            const agent = useragent(req.headers['user-agent']);
            const browser = `${agent?.browser?.name}/${agent?.browser?.version || ''}`;
            const system = `${agent?.os?.name}/${agent?.os?.version || ''}`;

            let {filter = null, sort, sc, page = 1, size = 10} = req.query;

            // 编码
            // let str = "Hello World & Welcome!";
            // let encodedStr = encodeURIComponent(str);
            // console.log(encodedStr); // 输出: Hello%20World%20%26%20Welcome%21
            // 解码
            // let encodedStr = "Hello%20World%20%26%20Welcome%21";
            // let decodedStr = decodeURIComponent(encodedStr);
            // console.log(decodedStr); // 输出: Hello World & Welcome!


            try {
                // 解析 filter 参数 {}
                let filter = {}
                if (req.query.filter) {
                    filter = JSON.parse(decodeURIComponent(filter))
                    console.log('filter1:', filter)
                }
                if (!req.query.filter) {
                    const params = {...req.query}
                    console.log('1params:', params)

                    delete params.sort
                    delete params.sc
                    delete params.page
                    delete params.size

                    console.log('2params:', params)

                    for (let key in params) {
                        console.log('key:', key)
                        // 如果值为数组，返回错误
                        if (Array.isArray(params[key])) {

                            // 是时间范围 ["2025-08-09 20:00:00", "2025-08-09 21:00:00"]
                            if (params[key]?.length === 2 && isValidDateTimeFormat(params[key][0]) && isValidDateTimeFormat(params[key][1])) {
                                filter[key] = {$gte: params[key][0], $lte: params[key][1]}
                            } else {
                                // 是数组
                                filter[key] = {$in: params[key]}

                            }

                        }
                        if (typeof params[key] === 'string') {
                            filter[key] = params[key]
                        }
                        console.log('filter2:', filter)
                    }
                }

                let sort = {}
                if (req.query.sort && req.query.sc) sort[req.query.sort] = Number(req.query.sc);
                if (Object.keys(sort).length) sort['_id'] = 1;  //辅助排序

                page = Number(page);
                size = Number(size);
                let skip = (Number(page) - 1) * Number(size);

                const count = await mongoose.connection.db.collection(name).countDocuments(filter);

                // 执行查询
                let data = await mongoose.connection.db
                    .collection(name).find(filter).sort(sort).skip(skip).limit(size).toArray();
                console.log('filter3:', filter)
                console.log('filter', filter)

                if (setDataAgain[name]) data = setDataAgain[name](data)

                // 保存日志
                await saveLog(mongoose, LOG_COLLECTION, {
                    collection: name,
                    params: req.query,
                    user,
                    IP,
                    browser,
                    system,
                    resultCount: data.length,
                    status: "success",
                    message: "查询成功",
                });

                return res.send({success: true, result: data, filter, name, sort, page, size, total: count});
            } catch (err) {
                await saveLog(mongoose, LOG_COLLECTION, {
                    collection: name,
                    params: req.query,
                    user,
                    IP,
                    browser,
                    system,
                    resultCount: 0,
                    status: "error",
                    message: err.message
                });
                return res.send({success: false, message: `查询时出错: ${err.message}`, filter, name});
            }
        });

    }
    // ===== 新增：日志查询接口（支持过滤） =====
    app.get(`${PREFIX}/logs`, async (req, res) => {
        try {
            let {
                user, collection, status, startTime, endTime,
                page = 1, size = 10
            } = req.query;

            // 安全地解析 sort 参数
            let sort = {}
            if (req.query.sort && req.query.sc) sort[req.query.sort] = Number(req.query.sc);
            if (Object.keys(sort).length) sort['_id'] = 1;  //辅助排序

            // 构建过滤条件
            let filter = {};
            if (user) filter.user = user;
            if (collection) filter.collection = collection;
            if (status) filter.status = status;

            if (startTime || endTime) {
                filter.time = {};
                if (startTime) filter.time.$gte = new Date(startTime);
                if (endTime) filter.time.$lte = new Date(endTime);
            }


            page = Number(page);
            size = Number(size);
            let skip = (Number(page) - 1) * Number(size);

            const logsCollection = mongoose.connection.db.collection(LOG_COLLECTION);

            const total = await logsCollection.countDocuments(filter);
            // 按时间倒序
            const logs = await logsCollection.find(filter).sort(sort).skip(skip).limit(size).toArray() || [];

            return res.send({
                success: true, result: logs, page, size, total, filter,
            });
        } catch (err) {
            console.error("Error querying logs:", err);
            return res.send({success: false, message: `查询日志时出错: ${err.message}`})
        }
    });

    // 启动服务
    app.listen(PORT, () =>
        console.log(`🚀 API server running at http://localhost:${PORT}${PREFIX}/{collection}`)
    );
}

startServer().catch(err => {
    console.error("❌ Failed to start server:", err);
});




